package Leetcode;

import java.util.HashSet;
import java.util.Set;

/**
 * 给定一个字符串 s ，请你找出其中不含有重复字符的 最长子串 的长度。
 * 例如：pwwkew 子串wke=3  bbbb 子串长度b=1 abcabcbb 子串abc=3  " " =1 au=2 dvdf=3
 */
public class 力扣3_无重复字符的最长子串 {
    public static void main(String[] args) {
        System.out.println(lengthOfLongestSubstring("pwwkew"));
    }

    /**
     * 官网滑动窗口
     */
    public static int lengthOfLongestSubstring(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        }
        int result = 0;
        int setIndex = 0;
        Set<Character> set = new HashSet<>(s.length());
        for (int i = 0; i < s.length(); i++) {
            // 每次循环前将前一个字符移除
            if (i != 0) {
                set.remove(s.charAt(i - 1));
            }
            // 移除重复条件后字符串列表从之前位置往后继续添加
            while (setIndex < s.length() && !set.contains(s.charAt(setIndex))) {
                set.add(s.charAt(setIndex));
                ++setIndex;
            }
            // 遇到重复后 获取当前长度
            result = Math.max(result, set.size());
        }
        return result;
    }

    /**
     * 每次获取一个开始结束的下标
     * 判断范围内是否有重复 重复移动下标 并计算长度
     */
    public static int lengthOfLongestSubstring1(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        }
        int l = 0;
        int r = 1;
        int subLength = 1;
        while (r <= s.length()) {
            CharSequence sub = s.subSequence(l, r);
            if (isRepeat(sub)) {
                if (l == r - 1) {
                    r++;
                } else {
                    l++;
                }
            } else {
                subLength = Math.max(subLength, sub.length());
                r++;
            }
        }
        return subLength;
    }

    public static boolean isRepeat(CharSequence sub) {
        Set<Character> set = new HashSet<>();
        for (int i = 0; i < sub.length(); i++) {
            if (set.contains(sub.charAt(i))) {
                return true;
            }
            set.add(sub.charAt(i));
        }
        return false;
    }
}
